package com.bd.scm.module.department.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bd.scm.dao.mapper.department.DtDepMapper;
import com.bd.scm.domain.dto.TreeNode;
import com.bd.scm.domain.dto.TreeSlots;
import com.bd.scm.domain.dto.department.DeptAgGridTree;
import com.bd.scm.domain.dto.login.LoginDto;
import com.bd.scm.domain.dto.tree.ZTree;
import com.bd.scm.domain.models.department.BdUserJob;
import com.bd.scm.domain.models.department.DtDep;
import com.bd.scm.module.common.CodeGenerate;
import com.bd.scm.module.department.service.IDtDepService;
import com.bd.scm.module.enums.CodeRuleEnum;
import com.bd.scm.module.common.BaseServiceImpl;
import com.bd.scm.module.enums.ExceptionEmun;
import com.bd.scm.module.exception.ScmException;
import com.bd.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.bag.SynchronizedSortedBag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;


import java.util.*;
import java.util.stream.Collectors;

/**
 * 部门服务实现类
 *
 * @author yufc
 * @since 2019-08-27
 */
@Service
@Slf4j
@CacheConfig(cacheNames = {"dept"})
public class DtDepServiceImpl extends BaseServiceImpl<DtDepMapper, DtDep> implements IDtDepService {

    @Autowired
    private DtDepMapper dtDepMapper;

    /**
     * 获取所有部门数据
     *
     * @return
     */
    @Override
    public List<DtDep> getDeptList(String queryMap) {
        QueryWrapper<DtDep> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(queryMap)) {
            queryMap = queryMap.substring(1, queryMap.length() - 1);
            List idList = Arrays.asList(queryMap.split(","));
            queryWrapper.in("dep_serial", idList);
        }
//        queryWrapper.le("dep_serial", "200061");
        return getList(queryWrapper);
    }


    /**
     * 获取部门树结构数据（只有key、title、children）
     *
     * @return
     */
    @Override
    @Cacheable(key = "'deptKeyName'")
    public List<TreeNode> getDeptTreeList(Long parentId) {
        String queryMap = null;

        List<DtDep> deptList = getDeptList(queryMap);

        if (CollectionUtils.isEmpty(deptList)) return null;

        List<TreeNode> treeList = createTree(parentId, deptList);
        return treeList;
    }


    /**
     * 获取2级部门数据  班次与部门使用
     *
     * @param parentId 父结点ID
     * @return
     */
    @Override
//    @Cacheable(key = "'zTree'")
    public List<ZTree> findDepList(Long parentId,List<String> deptIdList) {
        String deptIds = "";

        if(!CollectionUtils.isEmpty(deptIdList)){
            deptIds = org.apache.commons.lang3.StringUtils.join(deptIdList, ",");
        }

        List<DtDep> deptList = this.dtDepMapper.findDepList(deptIds);

        if (CollectionUtils.isEmpty(deptList)) {
            return null;
        }

        List<ZTree> treeList = createZTree(parentId, deptList);
        return treeList;
    }

    /**
     * 获取2级部门数据  规律班次与部门使用
     *
     * @param parentId 父结点ID
     * @return
     */
    @Override
//    @Cacheable(key = "'zTree'")
    public List<ZTree> findGlDepList(Long parentId, List<String> deptIdList) {
        String deptIds = "";

        if(!CollectionUtils.isEmpty(deptIdList)){
            deptIds = org.apache.commons.lang3.StringUtils.join(deptIdList, ",");
        }
        List<DtDep> deptList = this.dtDepMapper.findGlDepList(deptIds);

        if (CollectionUtils.isEmpty(deptList)) {
            return null;
        }

        List<ZTree> treeList = createZTree(parentId, deptList);
        return treeList;
    }

    /**
     * 获取部门树结构数据（包含部门表所有字段）
     *
     * @param parentId
     * @return
     */
    @Override
    @Cacheable(key = "'deptAll'")
    public List<DtDep> getDeptTreeListWithData(Long parentId) {
        String queryMap = null;
        List<DtDep> deptList = getDeptList(queryMap);

        if (CollectionUtils.isEmpty(deptList)) return null;

        List<DtDep> treeList = createTreeWithData(parentId, deptList);
        return treeList;
    }


    /**
     * 修改部门信息
     *
     * @param dept 部门对象
     * @return 返回影响行数，0表示更新失败
     */
    @Override
//    @CacheEvict(value = "deptTree", key = "'deptKeyName'")
//    @CacheEvict(value = "deptTreeAll", key = "'deptAll'")
    @Caching(evict = {@CacheEvict(key = "'deptAll'"), @CacheEvict(key = "'deptKeyName'")})
    public int edit(DtDep dept) {
        return dtDepMapper.updateById(dept);
    }


    /**
     * 新增部门
     *
     * @param dept 部门对象
     * @return 返回影响行数，0表示更新失败
     */
    @Override
//    @Caching(evict = {@CacheEvict(key = "'deptAll'"), @CacheEvict(key = "'deptKeyName'")})
    public int add(DtDep dept) {
        if (checkExist(dept.getDepParent(), dept.getDepName())) {
            throw new ScmException(ExceptionEmun.DEPT_ERROR_NAMEREPETITION);
        }

        Long id = Long.parseLong(getMaxId(CodeRuleEnum.DEPT).toString());
        dept.setDepSerial(id);

        //添加子部门
        DtDep maxNumberDept = selectMaxNoByParent(dept.getDepParent());
        if (maxNumberDept == null) {
            //为空表示当前节点下没有子部门
            DtDep parent = dtDepMapper.selectById(dept.getDepParent());

            dept.setDepNo(parent.getDepNo() + "00");
            //121数据库中没有该字段
            //dept.setIsParent(1D);
            dept.setDepOrder(1);
        } else {
            String number = CodeGenerate.DeptNumberGenerate(maxNumberDept.getDepNo());
            if ("".equals(number)) {
                throw new ScmException(ExceptionEmun.DEPT_ERROR_NUMBERCREATE);
            }
            dept.setDepNo(number);
            //121数据库中没有该字段
            //dept.setIsParent(0D);
            dept.setDepOrder(StringUtils.isEmpty(maxNumberDept.getDepOrder().toString()) ? 1 : maxNumberDept.getDepOrder() + 1);
        }
        dept.setDepRule("0");

        return dtDepMapper.insert(dept);
    }


    /**
     * 根据上级部门和部门名称查找同一上级部门是否有重名的部门
     *
     * @param depParent 上级部门ID
     * @param depName   部门名称
     * @return
     */
    private boolean checkExist(Integer depParent, String depName) {
        QueryWrapper<DtDep> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("dep_parent", depParent).eq("dep_name", depName);

        List<DtDep> list = dtDepMapper.selectList(queryWrapper);

        return list.size() > 0;
    }


    /**
     * 删除部门
     *
     * @param dept 部门对象
     * @return 返回影响行数，0表示更新失败
     */
    @Override
    @Caching(evict = {@CacheEvict(key = "'deptAll'"), @CacheEvict(key = "'deptKeyName'"), @CacheEvict(key = "'zTree'")})
    public String delete(DtDep dept) {
        //TODO 逻辑删除，不要物理删除
        String r = null;
        int i = dtDepMapper.selectChild(dept);
        if (i == 0) {
            dtDepMapper.delete(dept);
        } else {
            r = "该部门包含子部门，无法删除，请先删除该部门的子部门！";
        }
        return r;
    }


//    public int delete(DtDep dept) {
//        //TODO 判断部门是否能删除
//
//        //TODO 逻辑删除
//
//        return dtDepMapper.delete(dept);
//    }

    /**
     * 获取当前父节点下最大编号的记录
     *
     * @param parentId 父级部门Id
     * @return
     */
    @Override
    public DtDep selectMaxNoByParent(int parentId) {
        QueryWrapper<DtDep> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("dep_parent", parentId).orderByDesc("dep_no");

        List<DtDep> list = dtDepMapper.selectList(queryWrapper);

        return list.size() > 0 ? list.get(0) : null;
    }


    /**
     * 获取与搜索关键字相匹配的部门
     *
     * @param key
     * @return
     */
    @Override
    public List<String> searchTreeKeyList(String key) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.like("dep_name", key);

        List<DtDep> list = getList(queryWrapper);
        if (!CollectionUtils.isEmpty(list)) {
            List<String> listKeys = list.stream().map(e -> e.getDepSerial().toString()).collect(Collectors.toList());
            return listKeys;
        }
        return null;
    }

    /**
     * 获取岗位数据
     * @param parentId 父结点ID
     * @return
     */
    @Override
    public List<ZTree> getJobList(String parentId) {
        List<BdUserJob> deptList = this.dtDepMapper.findJobLists();

        if (CollectionUtils.isEmpty(deptList)) {
            return null;
        }
        return createJobZTree(parentId, deptList);
    }


    private List<DtDep> getList(QueryWrapper queryWrapper) {
        List<DtDep> list = dtDepMapper.selectList(queryWrapper);

        if (CollectionUtils.isEmpty(list)) {
            log.info("getList,部门数据为空");
        }

        return list;
    }


    /**
     * 递归生成部门树（只有key、title、children）
     * AntD版本
     *
     * @param parentId 父级ID
     * @param deptList 全部部门数据
     * @return
     */
    private List<TreeNode> createTree(Long parentId, List<DtDep> deptList) {

//        List<DtDep> parentList = deptList.stream().filter(a -> Long.parseLong(a.getDepParent().toString()) == parentId).collect(Collectors.toList());
        List<DtDep> parentList = deptList.stream().filter(a -> Long.parseLong(a.getDepParent().toString()) == parentId).sorted(Comparator.comparing(DtDep::getDepOrder)).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(parentList)) return null;

        List<TreeNode> listRtn = new ArrayList<>();

        parentList.forEach(row -> {
            TreeNode treeNode = new TreeNode();
            treeNode.setKey(row.getDepSerial().toString());
            treeNode.setTitle(row.getDepName());
            treeNode.setText(row.getDepName());
            treeNode.setChildren(createTree(row.getDepSerial(), deptList));

            listRtn.add(treeNode);
        });

        return listRtn;
    }


    /**
     * 递归生成部门树（包含部门表所有字段）
     * AntD版本
     *
     * @param parentId
     * @param deptList
     * @return
     */
    private List<DtDep> createTreeWithData(Long parentId, List<DtDep> deptList) {

        List<DtDep> parentList = deptList.stream().filter(a -> Long.parseLong(a.getDepParent().toString()) == parentId).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(parentList)) return null;

        List<DtDep> listRtn = new ArrayList<>();

        parentList.forEach(row -> {
            DtDep dep = row;

            dep.setKey(row.getDepSerial().toString());
            dep.setValue(row.getDepSerial().toString());
            dep.setTitle(row.getDepName());
            dep.setText(row.getDepName());
            dep.setChildren(createTreeWithData(row.getDepSerial(), deptList));

            TreeSlots treeSlots = new TreeSlots();
            treeSlots.setTitle("title");
            dep.setScopedSlots(treeSlots);

            listRtn.add(dep);
        });

        return listRtn;
    }


    @Override
//    @Cacheable(key = "'zTree'")
    public List<ZTree> getZTreeList(Long parentId, List<String> deptIdList) {

        String deptIds = "";

        if(!CollectionUtils.isEmpty(deptIdList)){
            deptIds = org.apache.commons.lang3.StringUtils.join(deptIdList, ",");
        }

        List<DtDep> deptList = this.dtDepMapper.findDepLists(deptIds);

        if (CollectionUtils.isEmpty(deptList)) {
            return null;
        }

        return createZTree(parentId, deptList);
    }

    /**
     * 获取zTree树结构数据
     *
     * @param parentId
     * @param deptList
     * @return
     */
    private List<ZTree> createJobZTree(String parentId, List<BdUserJob> deptList) {
        List<ZTree> listRtn = new ArrayList<>();

        if (deptList.size() <= 1) {
            for (BdUserJob row : deptList) {
                ZTree tree = new ZTree();
                if (parentId == "NULL") {
                    tree.setOpen(true);
                }
                tree.setId(row.getJobSerial());
                tree.setName(row.getJobName());
                tree.setTitle(row.getJobName());
                tree.setChildren(deptList.size() <= 1 ? null : createJobZTree(row.getJobSerial(), deptList));
                if (!CollectionUtils.isEmpty(tree.getChildren()) && tree.getChildren().size() > 0) {
                    tree.setParent(true);
                } else {
                    tree.setParent(false);
                }
                tree.setOpen(false);
                listRtn.add(tree);
            }
        } else {
            //        List<DtDep> parentList = deptList.stream().filter(a -> Long.parseLong(a.getDepParent().toString()) == parentId).collect(Collectors.toList());
            List<BdUserJob> parentList = deptList.stream().filter(a -> new String(a.getJobParent()).equals(new String(parentId))).sorted(Comparator.comparing(BdUserJob::getJobOrder)).collect(Collectors.toList());

            if (CollectionUtils.isEmpty(parentList)) {
                return null;
            }

            parentList.forEach(row -> {
                ZTree tree = new ZTree();
                if (parentId == "NULL") {
                    tree.setOpen(true);
                }
                tree.setId(row.getJobSerial());
                tree.setName(row.getJobName());
                tree.setTitle(row.getJobName());
                tree.setChildren(createJobZTree(row.getJobSerial(), deptList));
                if (!CollectionUtils.isEmpty(tree.getChildren()) && tree.getChildren().size() > 0) {
                    tree.setParent(true);
                } else {
                    tree.setParent(false);
                }
                tree.setOpen(false);
                listRtn.add(tree);
            });
        }
        return listRtn;
    }

    /**
     * 获取zTree树结构数据
     *
     * @param parentId
     * @param deptList
     * @return
     */
    private List<ZTree> createZTree(Long parentId, List<DtDep> deptList) {

        List<ZTree> listRtn = new ArrayList<>();

        if (deptList.size() <= 1) {
            for (DtDep row : deptList) {
                ZTree tree = new ZTree();
                if (parentId == 0) {
                    tree.setOpen(true);
                }
                tree.setId(row.getDepSerial().toString());
                tree.setName(row.getDepName());
                tree.setTitle(row.getDepName());
                tree.setChildren(deptList.size() <= 1 ? null : createZTree(row.getDepSerial(), deptList));
                if (!CollectionUtils.isEmpty(tree.getChildren()) && tree.getChildren().size() > 0) {
                    tree.setParent(true);
                } else {
                    tree.setParent(false);
                }
                tree.setOpen(false);
                listRtn.add(tree);
            }
        } else {
            //        List<DtDep> parentList = deptList.stream().filter(a -> Long.parseLong(a.getDepParent().toString()) == parentId).collect(Collectors.toList());
            List<DtDep> parentList = deptList.stream().filter(a -> Long.parseLong(a.getDepParent().toString()) == parentId).sorted(Comparator.comparing(DtDep::getDepOrder)).collect(Collectors.toList());

            if (CollectionUtils.isEmpty(parentList)) {
                return null;
            }

            parentList.forEach(row -> {
                ZTree tree = new ZTree();
                if (parentId == 0) {
                    tree.setOpen(true);
                }
                tree.setId(row.getDepSerial().toString());
                tree.setName(row.getDepName());
                tree.setTitle(row.getDepName());
                tree.setChildren(createZTree(row.getDepSerial(), deptList));
                if (!CollectionUtils.isEmpty(tree.getChildren()) && tree.getChildren().size() > 0) {
                    tree.setParent(true);
                } else {
                    tree.setParent(false);
                }
                tree.setOpen(false);
                listRtn.add(tree);
            });
        }
        return listRtn;
    }


    @Override
    public List<LoginDto> findDept(LoginDto loginDto) {
        return dtDepMapper.findDept(loginDto);
    }


    @Override
    public List<String> findDeptid(LoginDto loginDto) {
        return this.dtDepMapper.findDeptid(loginDto);
    }


    @Override
    public List<String> findSoleDeptid(LoginDto loginDto) {
        return this.dtDepMapper.findSoleDeptid(loginDto);
    }

    @Override
    public List<DeptAgGridTree> getAgTreeGridList(String depName) {
        return this.dtDepMapper.getAgTreeGridList(depName);
    }

    /**
     * 删除部门
     * @param dept  部门对象
     * @return
     */
    @Override
    public String deleteDtDep(DtDep dept) {
        //TODO 逻辑删除，不要物理删除
        String r = null;
        int i = this.dtDepMapper.selectChild(dept);
        if (i == 0) {
            this.dtDepMapper.deleteDtDep(dept);
        } else {
            r = "该部门包含子部门，无法删除，请先删除该部门的子部门！";
        }
        return r;
    }

    /**
     * 修改部门
     * @param dept  部门对象
     * @return
     */
    @Override
    public String updateDtDep(DtDep dept) {
        String r = null;
        //添加子部门
        DtDep maxNumberDept = selectMaxNoByParent(dept.getDepParent());
        if (maxNumberDept == null) {
            //为空表示当前节点下没有子部门
            DtDep parent = dtDepMapper.selectById(dept.getDepParent());

            dept.setDepNo(parent.getDepNo() + "00");
            //121数据库中没有该字段
            //dept.setIsParent(1D);
            dept.setDepOrder(1);
        } else {
            String number = CodeGenerate.DeptNumberGenerate(maxNumberDept.getDepNo());
            if ("".equals(number)) {
                throw new ScmException(ExceptionEmun.DEPT_ERROR_NUMBERCREATE);
            }
            dept.setDepNo(number);
            //121数据库中没有该字段
            //dept.setIsParent(0D);
            dept.setDepOrder(StringUtils.isEmpty(maxNumberDept.getDepOrder().toString()) ? 1 : maxNumberDept.getDepOrder() + 1);
        }
        dept.setDepRule("0");
        int i = this.dtDepMapper.updateDtDep(dept);
        if (i > 0) {
//            this.dtDepMapper.updateDtDepZi(dept);
        } else {
            r = "修改部门失败！";
        }
        return r;
    }

    /**
     * 根据部门名称，编号模糊查询部门
     * @param serchValue
     * @return
     */
    @Override
    public List<DtDep> findDtDepList(String serchValue) {
        return this.dtDepMapper.findDtDepList(serchValue);
    }
}
